package com.zhuhao.design_mode.structural_pattern.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 *
 * 动态代理工厂，对接口的实现类进行增强
 *
 * @Author halk
 * @Date 2020/11/17 17:14
 */
public class ProxyFactory {

    private final Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     * ClassLoader loader: 指定目标对象使用的类加载器，获取加载器的方法固定(xx.getClass().getClassLoader())
     * Class<?>[] interfaces: 目标对象实现的接口类型，使用泛型方法确认类型
     * InvocationHandler h： 事情处理执行目标对象的方法时，会触发事情处理器方法，会把当前执行的目标对象方法作为参数传入
     *
     * @return
     */
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new DaoProxy()
        );
    }

    /**
     * 对接口进行增强的实现
     *
     * @author halk
     * @date 2025/9/10 16:14
     **/
    class DaoProxy implements InvocationHandler {

        /**
         *
         * @param proxy 实际生成的代理对象实例（ITeacherDao的代理对象）
         * @param method 代理对象调用的方法
         * @param args 代理对象调用的方法的参数
         * @return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("正在调用方法: " + method.getName() + "()");
            System.out.println("调用方法的参数: " + Arrays.toString(args));

            // 可以对特定代理对象做特殊处理
            if (proxy instanceof ITeacherDao) {
                System.out.println("执行ITeacherDao相关增强逻辑");

//                //这里可以用生成的代理对象调用目标方法
//                //调用目标方法后，又会被代理会造成无限递归调用
//                ((ITeacherDao) proxy).teach();
            }

            System.out.println("代理执行前的逻辑");
            Object returnVal = method.invoke(target, args);
            System.out.println("代理执行后的逻辑");
            return returnVal;
        }
    }

}
